<template>
    <el-form :inline="true">
        <el-form-item label="关键字">
            <el-input v-model="searchRequest.keyword" placeholder="请输入查询关键字" autocomplete="off" />
        </el-form-item>
        <el-form-item>
            <el-button type="primary" @click="onSearch" v-permission="'role:query'"> 筛选 </el-button>
            <el-button type="info" @click="onReset" v-permission="'role:query'"> 重置 </el-button>
            <el-divider direction="vertical" />
            <el-button type="success" @click="onAdd" v-permission="'role:add'"> 添加 </el-button>
        </el-form-item>
    </el-form>
    <el-table :data="tableData" style="width: 100%">
        <el-table-column prop="roleName" label="角色名" width="150" />
        <el-table-column label="菜单权限" width="*">
            <template #default="scope">
                <el-text truncated>
                    <span v-html="scope.row.menusText"></span>
                </el-text>
            </template>
        </el-table-column>
        <el-table-column label="操作权限" width="*">
            <template #default="scope">
                <el-text truncated>
                    <span v-html="scope.row.operatorsText"></span>
                </el-text>
            </template>
        </el-table-column>
        <el-table-column label="操作" width="120">
            <template #default="scope">
                <el-button link type="primary" @click="onDelete(scope.row)" v-permission="'role:delete'">删除</el-button>
                <el-button link type="primary" @click="onEdit(scope.row)" v-permission="'role:edit'">修改</el-button>
            </template>
        </el-table-column>
    </el-table>
    <el-pagination style="margin-top: 5px" :page-size="PageConfig.PAGE_SIZE" :total="tableTotal"
        :current-page="searchRequest.pageIndex" @current-change="onPageChange" />
    <!--修改或添加弹窗-->
    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px" @close="dialogVisible = false"
        @open="onDialogOpen">
        <el-form ref="roleDataRef" :model="roleData" :rules="rules" label-width="auto">
            <el-form-item label="角色名" prop="roleName">
                <el-input autocomplete="off" v-model="roleData.roleName" placeholder="请输入角色名(不超过20个字符)" />
            </el-form-item>
            <el-form-item label="权限管理">
                <div style="display: flex; justify-content: space-between;width: 100%;height: 200px;">
                    <div style="border: 1px solid #EFEFEF;flex-grow: 1;width: 50%;">
                        <el-scrollbar>
                            <el-tree style="width: 100%;" ref="permissionRefMenus" :data="permissionMenus"
                                :props="permissionProps" node-key="permissionId" show-checkbox
                                :default-expanded-keys="['-1']" />
                        </el-scrollbar>
                    </div>
                    <div style="border: 1px solid #EFEFEF; flex-grow: 1;width: 50%;">
                        <el-scrollbar>
                            <el-tree style="width: 100%;" ref="permissionRefOperators" :data="permissionOperators"
                                :props="permissionProps" node-key="permissionId" show-checkbox
                                :default-expanded-keys="['-1']" />
                        </el-scrollbar>
                    </div>
                </div>
            </el-form-item>
            <el-form-item label="备注" prop="bak">
                <el-input type="textarea" autocomplete="off" v-model="roleData.bak" placeholder="请输入备注(不超过200个字符)" />
            </el-form-item>
        </el-form>
        <template #footer>
            <div>
                <el-button @click="dialogVisible = false">取消</el-button>
                <el-button type="primary" @click="onSave(roleDataRef)"> 确定 </el-button>
            </div>
        </template>
    </el-dialog>

</template>
<script setup>
import { ref, onMounted, reactive } from 'vue'
import api from '@/apis/api'
import { ElMessage, ElMessageBox } from 'element-plus'
import { DialogType, PageConfig, PermissionType } from '@/constant'
import { PermissionTree2List } from '@/utils/tools'

//筛选
const searchRequest = reactive({
    keyword: null,
    pageIndex: 1,
    pageSize: PageConfig.PAGE_SIZE
})
//表数据
const tableData = ref([])
const tableTotal = ref(0)

//表单数据

const roleDataRef = ref()
const roleData = reactive({
    roleId: null,
    roleName: null,
    bak: null,
    menus: [],
    operators: []
})
const rules = reactive({
    roleName: [{ required: true, message: "请输入角色名", trigger: "blur" }, { max: 20, message: "角色名不超过20个字符", trigger: "blur" }],
    bak: [{ max: 200, message: "备注不超过200个字符", trigger: "blur" }]
});
//弹窗
const dialogTitle = ref('角色信息')
const dialogVisible = ref(false)
const dialogFlag = ref(DialogType.VIEW)//dialog模式，view、add、edit

//权限
const permissionMenus = ref([{ permissionId: '-1', permissionName: '菜单权限', children: [] }])
const permissionOperators = ref([{ permissionId: '-1', permissionName: '操作权限', children: [] }])
const permissionProps = {
    label: 'permissionName',
    children: 'children',
}
const allPermissionMenus = ref([])
const allPermissionOperators = ref([])

const permissionRefMenus = ref()
const permissionRefOperators = ref()
onMounted(async () => {
    try {
        loadPermission()
        loadTable()
    } catch (error) {
        console.error('数据加载失败:', error)
    }
})
async function loadPermission() {
    api.permission.tree(PermissionType.MENU, resp => {
        allPermissionMenus.value = resp.data
        permissionMenus.value[0].children = resp.data
    })
    api.permission.tree(PermissionType.OPERATOR, resp => {
        allPermissionOperators.value = resp.data
        permissionOperators.value[0].children = resp.data
    })
}
async function loadTable() {
    api.role.pageList(searchRequest.pageIndex, PageConfig.PAGE_SIZE, searchRequest.keyword, resp => {
        let datas = [];
        for (let data of resp.data) {
            const _menuText = getPermissionText(data.menus);
            const _operatorText = getPermissionText(data.operators);
            datas.push({
                roleId: data.roleId,
                roleName: data.roleName,
                bak: data.bak,
                menus: data.menus,
                operators: data.operators,
                menusText: _menuText,
                operatorsText: _operatorText
            });
        }
        tableData.value = datas
        tableTotal.value = resp.rows
    })
}
async function onSearch() {
    searchRequest.pageIndex = 1
    loadTable()
}
async function onReset() {
    searchRequest.keyword = null
    searchRequest.pageIndex = 1
    loadTable()
}
async function onPageChange(pageIndex) {
    searchRequest.pageIndex = pageIndex
    loadTable()
}

//删除
async function onDelete(row) {
    // console.log(row)
    ElMessageBox.confirm('确定删除?', '确认',
        {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
        })
        .then(() => {
            //确认
            api.role.delete(row.roleId, resp => {
                onReset()
            })
        }).catch(() => {

        })
}
async function clearForm() {
    roleData.roleId = null
    roleData.roleName = null
    roleData.bak = null
    roleData.menus = []
    roleData.operators = []
}
async function onDialogOpen() {
    permissionRefMenus.value.setCheckedKeys(roleData.menus)
    permissionRefOperators.value.setCheckedKeys(roleData.operators)
}
//添加
async function onAdd() {
    dialogTitle.value = '添加角色'
    dialogFlag.value = DialogType.ADD
    clearForm()
    dialogVisible.value = true
}
//修改
async function onEdit(row) {
    dialogTitle.value = '修改角色信息'
    dialogFlag.value = DialogType.EDIT
    dialogVisible.value = true

    roleData.roleId = row.roleId
    roleData.roleName = row.roleName
    roleData.bak = row.bak
    //此逻辑必须在dialog的opend方法里边才能找的ref对象
    if (row.menus.length > 0) {
        let ids = []
        let menus = PermissionTree2List(row.menus)
        // console.log(menus)
        for (let p of menus) {
            if (!p.hasChildren) {
                ids.push(p.permissionId)
            }
        }
        roleData.menus = ids
    }
    if (row.menus.length > 0) {
        let ids = []
        let operators = PermissionTree2List(row.operators)
        // console.log(menus)
        for (let p of operators) {
            if (!p.hasChildren) {
                ids.push(p.permissionId)
            }
        }
        roleData.operators = ids
    }
}

//保存
async function onSave(formEl) {
    // console.log(roleData)
    // console.log(permissionRefMenus.value.getCheckedKeys())//获取叶子节点
    // console.log(permissionRefMenus.value.getHalfCheckedKeys()) //获取叶子节点上级
    if (!formEl) return
    let permissionIds = []//菜单+操作权限
    permissionIds.push(...permissionRefMenus.value.getCheckedKeys())//菜单子节点
    permissionIds.push(...permissionRefMenus.value.getHalfCheckedKeys().filter(id => id != "-1"))//菜单半选中节点（叶子节点的上级）

    permissionIds.push(...permissionRefOperators.value.getCheckedKeys())//操作子节点
    permissionIds.push(...permissionRefOperators.value.getHalfCheckedKeys().filter(id => id != "-1"))//操作半选中节点（叶子节点的上级）
    // console.log(permissionIds)
    await formEl.validate((valid, fields) => {
        if (valid) {
            if (dialogFlag.value == DialogType.ADD) {
                //添加
                api.role.add(roleData.roleName, roleData.bak, permissionIds, resp => {
                    clearForm()
                    ElMessage('添加成功')
                    onReset()//重新加载
                    dialogVisible.value = false
                })
            }
            else {
                //修改
                api.role.edit(roleData.roleId, roleData.roleName, roleData.bak, permissionIds, resp => {
                    clearForm()
                    ElMessage('修改成功')
                    onReset()//重新加载
                    dialogVisible.value = false
                })
            }
        }
    })
}
//根据权限树展示文字
function getPermissionText(permissionTree) {
    let text = "";
    if (permissionTree && permissionTree.length > 0) {
        for (let item of permissionTree) {
            if (item.children && item.children.length > 0) {
                text = text.concat(`&diams;${item.permissionName}：`);
                const childrenText = permission2Text(item.children);
                text = text.concat(`${childrenText}&nbsp;`)
            }
            else {
                text = text.concat(`&diams;${item.permissionName}&nbsp;`)
            }
        }
    }
    else {
        text = "无权限";
    }
    return text;
}

function permission2Text(tree) {
    let text = "";
    if (tree && tree.length > 0) {
        for (let item of tree) {
            text = text + item.permissionName + "，";
            const childrenText = permission2Text(tree.children);
            if (childrenText && childrenText.length > 0) {
                text = text + childrenText;
            }
        }
    }
    return text.slice(0, -1);
}
</script>
